package hotel.controller.room;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

import java.io.IOException;
import java.util.List;

import hotel.common.MsgBox;
import hotel.dao.HotelDao;
import hotel.modal.Room;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;

public class RoomManageController {
	@FXML private TableView<Room> tableView;
	@FXML private TableColumn<Room, String> RoomNoCol;
	@FXML private TableColumn<Room, String> typeCol;
	@FXML private TableColumn<Room, String> phoneNumCol;
	@FXML private TableColumn<Room, String> positionCol;
	@FXML private TableColumn<Room, Boolean> hourRoomCol;
	@FXML private TableColumn<Room, Integer> bedNumCol;
	@FXML private TableColumn<Room, Number> depositCol;
	@FXML private TableColumn<Room, Number> priceCol;
	@FXML private TableColumn<Room, Integer> principalCol;
	@FXML private TableColumn<Room, Integer> statusCol;
	@FXML private GridPane gridPane;
	@FXML private Button btnAdd;
	@FXML private TextField condField;
	@FXML private ChoiceBox<String> condCh;
	@FXML private Button btnQuery;
	@FXML private Button btnRefresh;
	@FXML private Button btnRoomTypeMange;
	
	@FXML
    public void initialize() {
		
		// 设置表格生成规则
		setCellFactory();
		
		// 设置监听
		setListener();
		//tableView.getColumns().remove(depositCol);
		//tableView.getColumns().remove(priceCol);
		//tableView.getColumns().remove(hourRoomCol);
		//tableView.getColumns().remove(statusCol);
		//tableView.getColumns().remove(principalCol);
		//tableView.getColumns().remove(bedNumCol);
		//tableView.getColumns().remove(phoneNumCol);
		//tableView.getColumns().remove(positionCol);
		
		
		// 加载数据
		loadData();
	}
	
	private void setCellFactory() {
		
		RoomNoCol.setCellFactory(col -> new TableCell<Room, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		typeCol.setCellFactory(col -> new TableCell<Room, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		positionCol.setCellFactory(col -> new TableCell<Room, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		phoneNumCol.setCellFactory(col -> new TableCell<Room, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		hourRoomCol.setCellFactory(col -> new TableCell<Room, Boolean>() {
			@Override
			protected void updateItem(Boolean item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == true)
					setText("是");
				else
					setText("否");
				setAlignment(Pos.CENTER);
			}
		});
		
		statusCol.setCellFactory(col -> new TableCell<Room, Integer>() {
			@Override
			protected void updateItem(Integer item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else {
					switch(item) {
					case 1: setText("可供"); break;
					case 2: setText("预定"); break;
					case 3: setText("入住"); break;
					case 4: setText("脏房"); break;
					case 5: setText("停用"); break;
					default: setText("未知"); break;
					}
				}
				setAlignment(Pos.CENTER);
			}
		});
		
		bedNumCol.setCellFactory(col -> new TableCell<Room, Integer>() {
			@Override
			protected void updateItem(Integer item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == null)
					setText(null);
				else
					setText(item.toString());
				setAlignment(Pos.CENTER);
			}
		});
		
		depositCol.setCellFactory(col -> new TableCell<Room, Number>() {
			@Override
			protected void updateItem(Number item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == null)
					setText(null);
				else
					setText(String.format("%.2f", item));
				setAlignment(Pos.CENTER);
			}
		});
		
		priceCol.setCellFactory(col -> new TableCell<Room, Number>() {
			@Override
			protected void updateItem(Number item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == null)
					setText(null);
				else
					setText(String.format("%.2f", item));
				setAlignment(Pos.CENTER);
			}
		});
		
		principalCol.setCellFactory(col -> new TableCell<Room, Integer>() {
			@Override
			protected void updateItem(Integer item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == null)
					setText(null);
				else
					setText(item.toString());
				setAlignment(Pos.CENTER);
			}
		});
		
		// 设置表格行右键菜单
		tableView.setRowFactory(new Callback<TableView<Room>, TableRow<Room>>() {
			@Override
			public TableRow<Room> call(TableView<Room> tableView) {
				final TableRow<Room> row = new TableRow<>();

				final ContextMenu rowMenu = new ContextMenu();
				MenuItem changeItem = new MenuItem("更改");

				changeItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						Room room = row.getItem();
						changeValue(room);
					}
				});

				MenuItem removeItem = new MenuItem("删除");

				removeItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						Room room = row.getItem();
						if (HotelDao.delete(room)) {
							tableView.getItems().remove(room);
							tableView.refresh();
						} else {
							MsgBox.showErrorDialog("错误", null, "删除失败！");
						}
					}
				});

				rowMenu.getItems().addAll(changeItem, removeItem);

				row.setOnMouseClicked(event -> { //鼠标双击
					if (event.getClickCount() == 2 && (!row.isEmpty())) {
						Room room = row.getItem();
						changeValue(room);
					}
				});

				// only display context menu for non-null items:
				row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty())).then(rowMenu)
						.otherwise((ContextMenu) null));
				return row;
			}
		});
	}
	
	public void loadData() {
		ObservableList<Room> data = tableView.getItems();
		data.clear();
		List<Room> list = HotelDao.getAllRoom();
		data.addAll(list);
	}
	
	// Event Listener on Button[#btnAdd].onAction
	@FXML
	public void onBtnAddAction(ActionEvent event) {
		FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/room/RoomChange.fxml"));
		try {
			Room room = new Room();
			Parent root = (Parent) fxmlLoader.load();
			RoomChangeController controller = fxmlLoader.<RoomChangeController>getController();
			controller.setAddMode();
			controller.setInitData(room); // 向子窗口传递数据
			Stage stage = new Stage();
			stage.setScene(new Scene(root));
			stage.setTitle("房间信息添加");
			stage.setResizable(false);
			stage.initModality(Modality.APPLICATION_MODAL);
			stage.showAndWait(); // 显示窗口并等待用户操作
			ObservableList<Room> data = tableView.getItems();
			if (room.isModified()) { // 判断是否被修改
				if (HotelDao.add(room)) {
					data.add(room);
				}else {
					MsgBox.showErrorDialog("错误", "房间信息添加失败！", "没有成功写入数据库！");
				}
			}
			tableView.refresh(); // 刷新表格
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void changeValue(Room room) {
		FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/room/RoomChange.fxml"));
		try {
			Parent root = (Parent) fxmlLoader.load();
			RoomChangeController controller = fxmlLoader.<RoomChangeController>getController();
			controller.setInitData(room); // 向子窗口传递数据
			Stage stage = new Stage();
			stage.setScene(new Scene(root));
			stage.setTitle("房间信息修改");
			stage.setResizable(false);
			stage.initModality(Modality.APPLICATION_MODAL);
			stage.showAndWait(); // 显示窗口并等待用户操作
			if (room.isModified()) { // 判断是否被修改
				if (!HotelDao.update(room)) {
					MsgBox.showErrorDialog("错误", "房间信息修改失败！", "没有成功写入数据库！");
				}
			}
			tableView.refresh(); // 刷新表格
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// Event Listener on Button[#btnQuery].onAction
	@FXML
	public void onBtnQueryAction(ActionEvent event) {
		this.condSearch();
	}
	
	private void condSearch() {
		String col = condCh.getSelectionModel().getSelectedItem();
		String cond = condField.getText();
		ObservableList<Room> data = tableView.getItems();
		List<Room> list = HotelDao.getRoomCondSearch(col, cond);
		data.clear();
		data.addAll(list);
		tableView.refresh();
	}
	
	private void setListener() {
		// 监听搜索框enter键按下
		condField.setOnKeyPressed(new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent ke) {
				if (ke.getCode().equals(KeyCode.ENTER)) {
					condSearch();
				}
			}
		});
	}
	
	// Event Listener on Button[#btnRefresh].onAction
	@FXML
	public void onBtnRefreshAction(ActionEvent event) {
		loadData();
	}
	
	// Event Listener on Button[#btnRoomTypeMange].onAction
	@FXML
	public void onBtnRoomTypeMangeAction(ActionEvent event) {
		FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/room/RoomTypeManage.fxml"));
		try {
			BorderPane bPane = (BorderPane)fxmlLoader.load();
			Stage stage = new Stage();
			stage.setScene(new Scene(bPane));
			stage.setTitle("房间类型管理");
			stage.setResizable(false);
			stage.initModality(Modality.APPLICATION_MODAL);
			Stage fStage = (Stage) btnRoomTypeMange.getScene().getWindow();
			fStage.hide();		 // 隐藏父窗口
			stage.showAndWait(); // 显示窗口并等待用户操作
			stage.close();
			loadData();		// 重新加载数据
			/*
			try {
				Thread.sleep(100); // 平滑显示
			} catch (InterruptedException e) {
				e.printStackTrace();
			}*/
			fStage.show();
			
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
}
